package com.powernode.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.constant.ProductConstants;
import com.powernode.domain.Category;
import com.powernode.exception.handler.BusinessException;
import com.powernode.mapper.CategoryMapper;
import com.powernode.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
@Service
@CacheConfig(cacheNames = "com.powernode.service.impl.CategoryServiceImpl")
@Slf4j
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService{

    /**
     * 查询所有种类 并保存进redis
     *
     * @return
     */
    @Override
    @Cacheable(key = ProductConstants.CATEGORY_ALL_LIST_KEY)
    public List<Category> queryCategoryList() {

        return this.list(new LambdaQueryWrapper<Category>().orderByAsc(Category::getSeq));
    }

    /**
     * 新增种类
     * 删除缓存
     * 当一个方法执行时,需要删除redis中两条缓存的话,需要使用@Caching注解
     * @param category
     * @return
     */
    @Override
    @Caching(evict = {
            @CacheEvict(key = ProductConstants.CATEGORY_ALL_LIST_KEY),
            @CacheEvict(key = ProductConstants.CATEGORY_FIRST_LIST_KEY)
    })
    public Boolean saveCategory(Category category) {
        // 设置父类id
        category.setParentId(category.getParentId() != null ? category.getParentId() : 0);

        // 设置创建时间 修改时间
        category.setCreateTime(new Date());
        category.setUpdateTime(new Date());

        boolean save = this.save(category);
        return save;
    }

    /**
     * 根据分类Id修改分类
     *
     * @param category
     * @return
     */
    @Override
    @Caching(evict = {
            @CacheEvict(key = ProductConstants.CATEGORY_ALL_LIST_KEY),
            @CacheEvict(key = ProductConstants.CATEGORY_FIRST_LIST_KEY)
    })
    public Boolean modifyCategoryById(Category category) {
        /**
         * 业务逻辑:
         *  首先根据id查询出是否是1级,如果是1级的话,则再查询一下它下面有没有二级
         *  如果有2级,则 不能修改,如果没有2级则可以修改
         *
         *  如果id查询出来是2级,则可以直接修改
         */

        Category byId = this.getById(category.getCategoryId());
        // 判断是否为1级,只需要判断他的parentId是否为0
        if (byId.getParentId() == 0) {
            // 查询1级下面有没有2级
            List<Category> categoryList = this.list(new LambdaQueryWrapper<Category>().eq(Category::getParentId, category.getCategoryId()));
            if (categoryList != null && categoryList.size() > 0) {
                throw new BusinessException("一级分类下面有二级分类,不能修改");
            }
        }
        // 判断有没有parentId 如果parentId为null,则说明想修改成1级,则给parentId赋值为0

        if (category.getParentId() == null) {
            category.setParentId(0L);
        }

        // 修改分类中的修改时间
        category.setUpdateTime(new Date());
        return this.updateById(category);
    }

    /**
     * 根据分类Id删除分类
     *
     * @param categoryId
     * @return
     */
    @Override
    @Caching(evict = {
            @CacheEvict(key = ProductConstants.CATEGORY_ALL_LIST_KEY),
            @CacheEvict(key = ProductConstants.CATEGORY_FIRST_LIST_KEY)
    })
    public Boolean removeCategoryById(Long categoryId) {
        /**
         * 业务逻辑,首先判断是否为1级,如果是1级,则判断有没有2级,如果有,则返回报错信息  不能删除
         *
         */
        List<Category> list = this.list(new LambdaQueryWrapper<Category>().eq(Category::getParentId, categoryId));

        if (list != null && list.size() > 0) {
            throw new BusinessException("该分类下面有二级分类,不能删除");
        }

        return this.removeById(categoryId);
    }

    /**
     * 查询一级分类
     *
     * @return
     */
    @Override
    @Cacheable(key = ProductConstants.CATEGORY_FIRST_LIST_KEY)
    public List<Category> queryFirstCategoryList() {
        /**
         * 因为分类最多二级,所以只需要将一级查询出来即可
         */
        List<Category> list = this.list(new LambdaQueryWrapper<Category>()
                .eq(Category::getParentId, 0)
                        .eq(Category::getStatus, 1)
                .orderByAsc(Category::getSeq));

        return list;
    }
}
